Tips and tricks for Julia practitioners — Julia Eindhoven
Patrick Altmeyer
Blurb
As a Julia practitioner you may want to publish your work in various forms: notebooks, Markdown, HTML, PDF and more. What if you could produce all these different outputs from the same input? I will share how I’ve been using Quarto with Julia, for package documentation, blogging and JuliaCon proceedings.
DISCLAIMER: Views presented in this presentation are my own. I do not represent Quarto or Posit (RStudio).
Quick Intro
Currently 2nd year of PhD in Trustworthy Artificial Intelligence at Delft University of Technology.
Working on Counterfactual Explanations and Probabilistic Machine Learning with applications in Finance.
Previously, educational background in Economics and Finance and two years at the Bank of England.
Enthusiastic about free open-source software, in particular Julia and Quarto.
What is Quarto?
Quarto – A New (Old) Way to Publish Science
Have used R Markdown for many years for essentially anything work-related.
Generate multiple different output formats with ease:
The old school: LaTeX and PDF (including Beamer); MS Office
The brave new world: beautiful HTML content
websites
e-books
apps
…
All of this starting from the same place …
A plain Markdown document blended with your favourite programming language of your choice and a YAML header defining your output.
Quarto with Julia
Setup
Preferred setup: VSCode, Quarto and Julia
Can switch between Jupyter and .qmd with ease.
When working with .qmd, code chunks connect to REPL.
Documenter.jl and Quarto
Generally play nicely with each other (both Markdown based).
format:commonmark:variant: -raw_html
You get some stuff for free, e.g. citation management.
Unfortunately lose support for cross-referencing …
Suggestion: Quarto for JuliaCon Proceedings
Quarto supports LaTex templates/classes …
… but why only publish proceedings in PDF form?
Quarto opens gateway to more innovative forms of publishing!
usingJavis, Animations, Colorswww_path ="www/images"size =600radius_factor =0.33functionground(args...)background("transparent")sethue("white")endfunctionrotate_anim(idx::Number, total::Number) distance_circle =0.875 steps =collect(range(distance_circle,1-distance_circle,length=total))Animation( [0, 1], # must go from 0 to 1 [0, steps[idx]*2π], [sineio()], )endtranslate_anim =Animation( [0, 1], # must go from 0 to 1 [O, Point(size*radius_factor, 0)], [sineio()],)translate_back_anim =Animation( [0, 1], # must go from 0 to 1 [O, Point(-(size*radius_factor), 0)], [sineio()],)julia_colours =Dict(:blue =>"#4063D8",:green =>"#389826",:purple =>"#9558b2",:red =>"#CB3C33")colour_order = [:red, :purple, :green, :blue]n_colours =length(julia_colours)functioncolor_anim(start_colour::String, quarto_col::String="#4b95d0")Animation( [0, 1], # must go from 0 to 1 [Lab(color(start_colour)), Lab(color(quarto_col))], [sineio()], )endvideo =Video(size, size)frame_starts =1:10:40n_total =250n_frames =150Background(1:n_total, ground)# Blob:functionelement(; radius =1)circle(O, radius, :fill) # The 4 is to make the circle not so smallend# Cross:functioncross(color="black";orientation=:horizontal)sethue(color)setline(10)if orientation==:horizontal out =line(Point(-size,0),Point(size,0), :stroke)else out =line(Point(0,-size),Point(0,size), :stroke)endreturn outendfor (i, frame_start) inenumerate(1:10:40)# Julia circles: blob =Object(frame_start:n_total, (args...;radius=1) ->element(;radius=radius))act!(blob, Action(1:Int(round(n_frames*0.25)), change(:radius, 1=>75))) # scale upact!(blob, Action(n_frames:(n_frames+50), change(:radius, 75=>250))) # scale up furtheract!(blob, Action(1:30, translate_anim, translate()))act!(blob, Action(31:120, rotate_anim(i, n_colours), rotate_around(Point(-(size*radius_factor), 0))))act!(blob, Action(121:150, translate_back_anim, translate()))act!(blob, Action(1:150, color_anim(julia_colours[colour_order[i]]), sethue()))# Quarto cross: cross_h =Object((n_frames+50):n_total, (args...) ->cross(;orientation=:horizontal)) cross_v =Object((n_frames+50):n_total, (args...) ->cross(;orientation=:vertical))endrender( video; pathname =joinpath(www_path, "julia_quarto.gif"),)
LaplaceRedux.jl is a small package that can be used for effortless Bayesian Deep Learning and Logistic Regression trough Laplace Approximation. It is inspired by this Python library and its companion paper.
Plugin Approximation (left) and Laplace Posterior (right) for simple artificial neural network.
Simulation of changing posteriour predictive distribution. Image by author.
ConformalPrediction.jl is a package for Uncertainty Quantification (UQ) through Conformal Prediction (CP) in Julia. It is designed to work with supervised models trained in MLJ(Blaom et al. 2020). Conformal Prediction is distribution-free, easy-to-understand, easy-to-use and model-agnostic.
Conformal Prediction in action: Prediction sets for two different samples and changing coverage rates. As coverage grows, so does the size of the prediction sets.
More Resources 📚
Read on …
Related blog post (hosted on this website that itself is built with Quarto and involves lots of Julia content).
Julia to Quarto animation. Source: author (heavily borrowing from Javis.jltutorial)
References
Blaom, Anthony D., Franz Kiraly, Thibaut Lienart, Yiannis Simillides, Diego Arenas, and Sebastian J. Vollmer. 2020. “MLJ: A Julia Package for Composable Machine Learning.”Journal of Open Source Software 5 (55): 2704. https://doi.org/10.21105/joss.02704.